﻿/*
 * Created by SharpDevelop.
 * User: Hellen(LongFan)
 * Date: 2015/12/24
 * Time: 20:33
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.IO;
using System.IO.Ports;
using System.Threading;			//多线程
using System.Windows.Forms;
using System.Text;
using System.Collections.Concurrent;

namespace Comm
{
	/// <summary>
	/// Description of DealDataThreadClass.
	/// </summary>
	public class DealDataThread
	{
		//the data is Byte format or not. False : the data is Uint16 Format.
		public static bool ByteFormat = false;
		//check the data show box show hex or string. true : show hex
		public static bool ShowHex = true;
		//control the RawTextBox to show data or not. true : show data
		public static bool TextShowEnable = true;
		//the thread is running or not, if is true, the thread is keep running
		private volatile bool DealDataThIsRuning = false;
		//The thread is working or not, if is true, something is doing, may write file, so the file can not be close
		public static bool DealDataThWorking = false;
		//dealing data or not, if is true, write data to file and showdata
		public static bool DataDealing = false;
		
		//the delegate, thread to refresh the texbox
		public delegate void UpdataInterFaceInvokeDelegate(string s);
		public UpdataInterFaceInvokeDelegate MyUpdataInvokeDelegate;
		
		private StreamWriter FileWrStream;
		
		private Thread MyTh;
		
		public void StartDealThread(ref StreamWriter sw)
		{
			FileWrStream = sw;
			//start the thread while
			DealDataThIsRuning = true;
			//start the thread
			MyTh = new Thread(new ThreadStart(DealDataFun));
			MyTh.Name = "DealDataThread";
			MyTh.Start();
			//wait the thread to start
			while(!MyTh.IsAlive);
		}
		public void StopDealThread()
		{
			DataDealing = false;			//stop the data deal function
			DealDataThIsRuning = false;		//stop the main while
			while(DealDataThWorking)		//wait the deal process end
				Application.DoEvents();
		}
		//The threat function to deal the data received
		private void DealDataFun()
		{
			byte[] ReceviedByte = new byte[2];
			long StartTicks = 0;
			long DeltaTicks = 0;
			//WaitTicks equal 4bit times
			long WaitTicks = (1000000000/((long)MyCommClass.SBaudRate))*4;
			UInt16 ReIntData = 0;
			if(ByteFormat)
			{	//not construct the data
				while(DealDataThIsRuning)
				{
					if(!DataDealing)
					{//fist open comm and no data to deal, sleep 100ms, reduce the cpu
						Thread.Sleep(50);
					}
					while(DataDealing)
					{	
						DealDataThWorking = true ;
						
						if(1 <= MainForm.MyReDataQueue.Count)
						{	//the queue have data, write the data to file
							MainForm.MyReDataQueue.TryDequeue(out ReceviedByte[0]);
							
							FileWrStream.WriteLine(
								Convert.ToString(ReceviedByte[0])+ "," 
								+Convert.ToString(ReceviedByte[0],8)+ ","
							);
							//updata UI RawTextBox
							if(TextShowEnable)
							{//enable the data to showed on textbox, invoke the event
								if(ShowHex)
								{//show data in hex format
									string HexString = String.Format( "0x{0:x} ",int.Parse(Convert.ToString(ReceviedByte[0])) );
									MyUpdataInvokeDelegate(HexString);
								}
								else
								{//show data in string format
									MyUpdataInvokeDelegate(Encoding.UTF8.GetString(ReceviedByte));
								}
							}
							//updata the ticks
							StartTicks = DateTime.Now.Ticks;
						}
						else
						{	//the queue is empty, wait 4bit times, 
							//if also have no data write 1 frame "0" to the file,
							//the comm think to no data 
							DeltaTicks = DateTime.Now.Ticks - StartTicks;
//							if(
//								WaitTicks < DeltaTicks && DeltaTicks < (WaitTicks/4*10)
//							   )
//							{
//								//The port have no data transfer or puse, Write one frame zero
//								FileWrStream.WriteLine(
//									Convert.ToString(0)+ "," 
//									+Convert.ToString(0)+ ","
//								);
//								//updata UI
//								MyUpdataInvokeDelegate(Convert.ToString(0));
//							}
							if( DeltaTicks > (WaitTicks * 5))
							{//stop the deal data function
								DataDealing = false;
								FileWrStream.WriteLine( "TooLong"+ "," +"TooLong"+ "," );
							}
						}
						//all things done
						DealDataThWorking = false;					
					}
				}
			}
			else
			{	//construct the to uint16
				while(DealDataThIsRuning)
				{
					if(!DataDealing)
					{//no data to deal, sleep 100ms, reduce the cpu
						Thread.Sleep(5);
					}
					while(DataDealing)
					{	
						DealDataThWorking = true ;
						
						if(2 <= MainForm.MyReDataQueue.Count)
						{	//when received datat count >=2 ,dequeue and write file in integrate
							MainForm.MyReDataQueue.TryDequeue(out ReceviedByte[1]);
							MainForm.MyReDataQueue.TryDequeue(out ReceviedByte[0]);
							ReIntData = BitConverter.ToUInt16(ReceviedByte,0);
							
							FileWrStream.WriteLine(
								Convert.ToString(ReIntData)+ "," 
								+Convert.ToString(ReIntData,16)+ ","
							);
							//updata UI
							if(TextShowEnable)
							{//enable the data to showed on textbox, invoke the event
								if(ShowHex)
								{
									string HexString = String.Format( "0x{0:x} ", ReIntData );
									MyUpdataInvokeDelegate(HexString);
								}
								else
								{
									MyUpdataInvokeDelegate(Convert.ToString(ReIntData));
								}
							}
							//updata the ticks
							StartTicks = DateTime.Now.Ticks;
						}
						else
						{	//the queue is empty, wait 4bit times
							DeltaTicks = DateTime.Now.Ticks - StartTicks;

							if( DeltaTicks > (WaitTicks * 5))
							{//if the delta time > 2byte times, stop the deal data function
								DataDealing = false;
								FileWrStream.WriteLine( "TooLong"+ "," +"TooLong"+ "," );
							}
						}
						DealDataThWorking = false ;
					}
				}				
			}
		}
	}	
}
